Skip to content
This repository was archived by the owner on Oct 1, 2019. It is now read-only.

Update Python integration #15

Closed
wants to merge 14 commits into from
Closed

Update Python integration #15

wants to merge 14 commits into from

Conversation

taion
Copy link
Contributor

@taion taion commented Dec 27, 2017

Not quite ready to go yet. Need to fix tests.

@taion taion changed the title [WIP] Update Python integration Update Python integration Dec 27, 2017
@taion
Copy link
Contributor Author

taion commented Dec 27, 2017

Should be good to go now. Might need to iterate a bit on the pyenv caching – it's better to cache the artefacts in .pyenv than the build cache.

with open("tmp/index.html"):
print("great")

with A() as X:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what the what?

@taion
Copy link
Contributor Author

taion commented Dec 27, 2017

Got a fix coming in a bit. This is all prep for #8.

]);
}

case "withitem": {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no such node type


const n = path.getValue();
if (n.body.length === 1 && n.body[0].ast_type === "With") {
path.each(p => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this idiomatic? i couldn't find a better way but i might not have looked hard enough

the idea is that body is an array, but in this case it's of length 1, so we want to call something on it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe:

return concat(
  path.map(
    p => printPython2With(p, items, print),
    "body"
  )
)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. Now I feel embarrassed for not thinking of that. Thanks!

@@ -631,6 +631,10 @@ function genericPrint(path, options, print) {
: printPython2With(path, [], print); // Python 2
}

case "withitem": {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never mind

.travis.yml Outdated
env:
global:
- PYTHON_VERSIONS="2.7.11 3.6.3"
matrix:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this runs a separate build for each version of python under test, rather than a single build that tests both pythons


base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

sys.path.insert(0, os.path.join(base_dir, 'vendor'))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've seen this pattern used elsewhere for CLI-y things where messing with the global Python path isn't a problem. I like that this hides the vendoring details from the caller.

It's also good to split out vendored things from things that are patched from upstream.

if (error) {
throw new Error(error);
function parse(text) {
const executionResult = spawnSync("python", ["-m", "prettier.parser"], {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you get a bit more flexibility when you run something as a module... you can do things like relative imports, which are sorta handy

@@ -1 +1 @@
run_spec(__dirname, ["python"], { pythonVersion: "3" });
run_spec(__dirname, ["python"], ">=3.6");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might as well... python 3.5 still sees some use, since it's what some of the active ubuntu LTS versions still ship

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Elasticbeanstalk (AWS) is stuck to python 3.4, I'd keep support for 3.4+ if possible

const source = read(path).replace(/\r\n/g, "\n");

const mergedOptions = Object.assign({}, options, {
parser: parsers[0]
});
const output = prettyprint(source, path, mergedOptions);
test(`${filename} - ${mergedOptions.parser}-verify`, () => {
expect(raw(source + "~".repeat(80) + "\n" + output)).toMatchSnapshot(
expect(raw(source + "~".repeat(79) + "\n" + output)).toMatchSnapshot(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was a silly change, but 79 makes more sense than 80 if you know it's going to be python code formatted to 79 chars

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should do .repeat(mergedOptions.printWidth). FYI I'd like to eventually share this file from Prettier as a package.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Merging these would be cool. We'd still have to wrap it for Python to do the version thing, though.

with open("tmp/index.html") as f:
index = f.read()

with open("tmp/index.html"):
print("great")

with A() as X:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and as a result of the build changes, we now automatically flag unnecessary 2/3 inconsistencies like these

(this was the only one)

function parse(text) {
const executionResult = spawnSync("python", ["-m", "prettier.parser"], {
env: {
PATH: process.env.PATH,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is so the virtualenv python gets picked up. i don't think we need anything else from env here

install:
- yarn install
before_install:
- export PYTHON_BUILD_CACHE_PATH="/home/travis/.pyenv_cache"
- curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out pyenv is already available on Travis (even when the language is node_js), and they have a decent selection of versions already installed.

@@ -4,22 +4,19 @@ node_js:
- 6
- 8
- 9
env:
- PYTHON_VERSION=2.7.14
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2.7.14 is the current release here; 2.7.11 is two years old and hasn't been current for a year and a half

'start': token.startpos,
'end': token.endpos,
}
for token in atok.tokens if token.type == tokenize.COMMENT
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolves https://github.com/prettier/prettier-python/pull/9/files#r158746577 and correspondingly fixes comment handling in python 2

@taion
Copy link
Contributor Author

taion commented Dec 31, 2017

Any updates here? This PR is unfortunately a mix of a few different things, but I think it sets a lot of pieces in place for further work:

  1. Check that we get the same results for Python 2 and Python 3
  2. Use build matrix for Python versions as well as Node versions
  3. Split out local Python code from vendored/patched Python libraries
  4. Fix a bug with printing "with" statements

I'd like to use this as a starting point for leveraging existing Python tools to make it easier to handle edge cases here.

@@ -29,16 +39,26 @@ function run_spec(dirname, parsers, options) {
filename[0] !== "." &&
filename !== "jsfmt.spec.js"
) {
if (!semver.satisfies(PYTHON_VERSION, versionRange)) {
// Skip each test here with the snapshot name below to avoid obsolete
// snapshot failures.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But they are obsolete, right?

Copy link
Contributor Author

@taion taion Dec 31, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to clarify the comment a bit.

The idea is that we run the same tests for both Python 2 and Python 3. However, some of these tests can't be run for Python 2.

For those tests, we skip them when the system Python is Python 2 – but if we don't explicitly skip them like this, then they throw off "obsolete snapshot" failures.

Those failures would be correct if we were only dealing with Python 2, but it's more that they're not pertinent to the test suite as currently run.

@taion
Copy link
Contributor Author

taion commented Jan 4, 2018

Any updates here? I can rebase this if we think this is the right approach.

@patrick91
Copy link
Member

I'll try to have a good look this weekend, thanks, and sorry for the delay :)

Copy link
Member

@patrick91 patrick91 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@taion this is good to go, can you rebase an fix the conflicts? Then I'll merge!

@taion
Copy link
Contributor Author

taion commented Feb 20, 2018

I don't think I'm going to have time to pick up on this again any time soon. Can someone else take over this PR?

@taion
Copy link
Contributor Author

taion commented Aug 16, 2018

Not planning on doing further work on this. We've switched to Black for the time being anyway.

@taion taion closed this Aug 16, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants